#ifndef OURSEMANTICANALYZER_H_
#define OURSEMANTICANALYZER_H_

#include "SemanticNodeProgram.h"
#include "SemanticNodeNamespace.h"
#include "SemanticNodeEnum.h"
#include "SemanticNodeField.h"
#include "SemanticNodeSimulation.h"
#include "SemanticNodeExpression.h"
#include "SemanticNodeInstanceOf.h"
#include "SemanticNodeClass.h"
#include "SemanticNodeCreateArray.h"
#include "SemanticNodeConstructObject.h"
#include "SemanticNodeCast.h"
#include "SemanticNodeVariableName.h"
#include "SemanticNodeModel.h"
#include "SemanticNodeConstructor.h"
/** Revise these includes! */
#include "SemanticNodeMethod.h"
#include "SemanticNodeProperty.h"
#include "../syntax_tree.h"
#include "../main_container.h"


class SemanticNodeBlockTerminate;
class SemanticNodeBlockGenerate;
class SemanticNodeBlockAdvance;
class SemanticNodeBlockEnter;
class SemanticNodeBlockLeave;
class SemanticNodeBlockSeize;
class SemanticNodeBlockRelease;
class SemanticNodeBlockInqueue;
class SemanticNodeBlockOutqueue;
class SemanticNodeBlockArrive;
class SemanticNodeBlockDepart;
class SemanticNodeBlockModelInstance;
class SemanticNodeBlockGoto;
class SemanticNodeBlockIf;
class SemanticNodeBlockWait;
class SemanticNodeBlockJoinGroup;
class SemanticNodeBlockLeaveGroup;
class SemanticNodeBlockCreate;
class SemanticNodeBlockSplit;
class SemanticNodeBlockGather;
class SemanticNodeBlockExecute;


extern MainContainer *CompilerData;

class OurSemanticAnalyzer {
public:

//private:
	static std::vector<const SyntaxTreeNode *> findValueProductions(const SyntaxTreeNode *expressionNode);

	static SemanticNodeClass *analyzeNodeClass(const SyntaxTreeNode *classNode, SemanticNode *parent);
	static SemanticNodeExpression *analyzeNodeExpression(const SyntaxTreeNode *expressionNode, SemanticNode *parent);
	static SemanticNodeInstanceOf *analyzeNodeInstanceOf(const SyntaxTreeNode *instanceOfNode, SemanticNode *parent);
	static SemanticNodeCreateArray *analyzeNodeCreateArray(const SyntaxTreeNode *createArrayNode, SemanticNode *parent);
	static SemanticNodeConstructObject *analyzeNodeConstructObject(const SyntaxTreeNode *constructObjectNode, SemanticNode *parent);
	static SemanticNodeCast *analyzeNodeCast(const SyntaxTreeNode *castNode, SemanticNode *parent);
	static SemanticNodeVariableName *analyzeNodeVariableName(const SyntaxTreeNode *variableNameNode, SemanticNode *parent);
	static std::vector<SemanticNodeExpression *> analyzeNodeArgument(const SyntaxTreeNode *argumentsNode, SemanticNode *parent);
	static SemanticNodeModel *analyzeNodeModel(const SyntaxTreeNode *modelNode, SemanticNode *parent);
	static std::vector<SemanticNodeField *> analyzeNodeParameters(const SyntaxTreeNode *parametersNode, SemanticNode *parent);
	static SemanticNodeBlockTerminate *analyzeNodeBlockTerminate(const SyntaxTreeNode *terminateNodeParent, SemanticNode *parent);
	static SemanticNodeBlockGenerate *analyzeNodeBlockGenerate(const SyntaxTreeNode *generateNodeParent, SemanticNode *parent);
	static SemanticNodeBlockAdvance *analyzeNodeBlockAdvance(const SyntaxTreeNode *advanceNodeParent, SemanticNode *parent);
	static SemanticNodeBlockEnter *analyzeNodeBlockEnter(const SyntaxTreeNode *enterNodeParent, SemanticNode *parent);
	static SemanticNodeBlockLeave *analyzeNodeBlockLeave(const SyntaxTreeNode *leaveNodeParent, SemanticNode *parent);
	static SemanticNodeBlockSeize *analyzeNodeBlockSeize(const SyntaxTreeNode *seizeNodeParent, SemanticNode *parent);
	static SemanticNodeBlockRelease *analyzeNodeBlockRelease(const SyntaxTreeNode *releaseNodeParent, SemanticNode *parent);
	static SemanticNodeBlockInqueue *analyzeNodeBlockInqueue(const SyntaxTreeNode *inqueueNodeParent, SemanticNode *parent);
	static SemanticNodeBlockOutqueue *analyzeNodeBlockOutqueue(const SyntaxTreeNode *outqueueNodeParent, SemanticNode *parent);
	static SemanticNodeBlockArrive *analyzeNodeBlockArrive(const SyntaxTreeNode *arriveNodeParent, SemanticNode *parent);
	static SemanticNodeBlockDepart *analyzeNodeBlockDepart(const SyntaxTreeNode *departNodeParent, SemanticNode *parent);
	static SemanticNodeBlockModelInstance *analyzeNodeBlockModelInstance(const SyntaxTreeNode *modelInstanceNodeParent, SemanticNode *parent);
	static SemanticNodeBlockGoto *analyzeNodeBlockGoto(const SyntaxTreeNode *gotoNodeParent, SemanticNode *parent);
	static SemanticNodeBlockIf *analyzeNodeBlockIf(const SyntaxTreeNode *ifNodeParent, SemanticNode *parent);
	static SemanticNodeBlockWait *analyzeNodeBlockWait(const SyntaxTreeNode *waitNodeParent, SemanticNode *parent);
	static SemanticNodeBlockJoinGroup *analyzeNodeBlockJoinGroup(const SyntaxTreeNode *joinGroupNodeParent, SemanticNode *parent);
	static SemanticNodeBlockLeaveGroup *analyzeNodeBlockLeaveGroup(const SyntaxTreeNode *leaveGroupNodeParent, SemanticNode *parent);
	static SemanticNodeBlockCreate *analyzeNodeBlockCreate(const SyntaxTreeNode *createNodeParent, SemanticNode *parent);
	static SemanticNodeBlockSplit *analyzeNodeBlockSplit(const SyntaxTreeNode *splitNodeParent, SemanticNode *parent);
	static SemanticNodeBlockGather *analyzeNodeBlockGather(const SyntaxTreeNode *gatherNodeParent, SemanticNode *parent);
	static SemanticNodeBlockExecute *analyzeNodeBlockExecute(const SyntaxTreeNode *executeNodeParent, SemanticNode *parent);
};

#endif /* OURSEMANTICANALYZER_H_ */
